require "common"

function sel_dist_num_pro(count, inStr)
	t = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30}
	for i=1,string.len(inStr),2 do
		local temp = string.sub(inStr,i,i+1)
		table.foreachi(t, function(i, v) if v==tonumber(temp) then table.remove(t, i) end end)
	end

	selected={};
	math.random(0,#t);
	math.randomseed(microtime()*1000000);
	if #t<=count then return t end
	while #selected < count do
		math.random(#t);
		table.insert(selected, table.remove(t,math.random(#t)));
	end
	return selected;
end


--===============�н�����ʽ�㷨============================
function QlcComppute(nTotal, nMaxRed, nMaxBlue)
	local nNum = {0, 0, 0, 0, 0, 0, 0,}
	local dothing = 0
	for i = 4, nMaxRed do
		for j = 0, nMaxBlue do
			if (7 - i) * 2 + (1 - j) <= 0 or (7 - i) * 2 + (1 - j) >= 8 then
				dothing = dothing + 1
			else
				nNum[(7 - i) * 2 + (1 - j)] = nNum[(7 - i) * 2 + (1 - j)] + combination(nMaxRed, i) * combination(nTotal - nMaxRed - nMaxBlue, 7 - i - j)
			end
		end
	end
	return nNum--[1]..","..nNum[2]..","..nNum[3]..","..nNum[4]..","..nNum[5]..","..nNum[6]..","..nNum[7]

end

--==================�����н���ѯ�㷨==========================
function QlcCompputeDT(nTotal, nTotalDT, nMaxRedDT, nMaxBlueDT, nMaxRed, nMaxBlue)
		--[[int nTotalDT = 4;        //�ܵ������
        int nMaxRedDT = 3;        //��������л����Ÿ���
        int nMaxBlueDT = 0;        //����������ر�Ÿ���
        int nTotal = 10;        //���������
        int nMaxRed = 3;        //��������л����Ÿ���
        int nMaxBlue = 1;        //����������ر�Ÿ���(10,4,3,0,3,1)
        int nNum[8] = {0, 0, 0, 0, 0, 0, 0, 0};]]
		local dothing = 0
        local nNum = {0, 0, 0, 0, 0, 0, 0, 0}

		for i = 0, nMaxRed do
			for j = 0, nMaxBlue do
				if (7 - i - nMaxRedDT) * 2 + (1 - j - nMaxBlueDT) <= 0 or (7 - i - nMaxRedDT) * 2 + (1 - j - nMaxBlueDT) >= 8 or 7 - nTotalDT - i - j < 0 or nTotal - nMaxRed - nMaxBlue < 0 or nMaxRed < 0 then
					dothing = dothing + 1
				else
					nNum[(7 - i - nMaxRedDT) * 2 + (1 - j - nMaxBlueDT)] = nNum[(7 - i - nMaxRedDT) * 2 + (1 - j - nMaxBlueDT)] + combination(nMaxRed, i) * combination(nTotal - nMaxRed - nMaxBlue, 7 - nTotalDT - i - j)
				end
			end
		end
		return nNum--[1]..","..nNum[2]..","..nNum[3]..","..nNum[4]..","..nNum[5]..","..nNum[6]..","..nNum[7]
end
--�����ַ�������
function sort_str( num )
	local out = ""
	local st = {}
	local len = string.len( num )
	if len%2 ~= 0 then
		return nil
	end

	for i=1,len,2 do
		c = string.sub(num,i,i+1)
		if tonumber(c) > 30 or tonumber(c) <1 then return nil end
		if not in_table( c, st ) then
			table.insert( st, c )
		else
			return nil
		end
	end
	table.sort(st)
	for i=1,table.getn( st ) do
		out = out..st[i]
	end
	return out
end

function in_table ( e, t )
	for _,v in pairs(t) do
		if (v==e) then return true end
	end
	return false
end



--����ע��,��Ͷ�� , Ͷע��, ָ�
function random_qlc( butType, inStr )
	local butNum = 1
	local butPower = 1
	local zlStr = ""
	local butStr = ""
	local itemList = {}
	local itemLen = 0;
	itemList = Split( inStr, "#" )
	itemLen = table.getn( itemList )

	--��ʽ��ѡ
	if butType == '1' then
		butNum = tonumber(itemList[1])
		if itemLen>2 or itemLen<1 or not butNum or butNum > 5 or butNum < 1  or (itemList[2] and string.find(itemList[2],"%D")) then
			return 0
		end
		if tonumber( itemList[2] ) then butPower = tonumber( itemList[2] ) else butPower = 1 end
		if butPower >99 or butPower < 1 then return 0 end

		for i=1,butNum do
			local nums = sel_dist_num(7,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30)
			table.sort(nums)
			zlStr = zlStr..format_num(nums[1])..format_num(nums[2])..format_num(nums[3])..format_num(nums[4])..format_num(nums[5])..format_num(nums[6])..format_num(nums[7])

			if i<butNum then zlStr = zlStr.."**" end
		end
		zlStr = zlStr.."#"..butPower
		butNum,butPower,butStr = check_qlc('1', zlStr)

	--�������
	elseif butType == '5' then
		local jItem = Split( inStr, "#" )

		if #jItem > 3 or #jItem<2 or string.find(jItem[1],"%D") or string.find(jItem[2], "%D")  or (jItem[3] and string.find(jItem[3],"%D")) then
			return 0
		end
		butNum = tonumber(jItem[2])

		if tonumber( itemList[3] ) then butPower = tonumber( itemList[3] ) else butPower = 1 end
		if butPower >99 or butPower < 1 then return 0 end

		if butNum > 5 or butNum < 1 or string.len(jItem[1])%2 ~= 0 or string.len(jItem[1]) < 2 or string.len(jItem[1]) > 12 then
			return 0
		end

		local rest = 7 - string.len(jItem[1])/2
		for i=1,butNum do
			local nums = sel_dist_num_pro(7, jItem[1])

			zlStr = zlStr..jItem[1]
			for j=1,rest do
				zlStr = zlStr..format_num(nums[j])
			end

			if i<butNum then zlStr = zlStr.."**" end
		end
		zlStr = zlStr.."#"..butPower
		butNum,butPower,butStr = check_qlc('1', zlStr)


	end

	return butNum, butPower, butStr, zlStr
end




--����ע��,��Ͷ��,Ͷע��
function check_qlc( butType, inStr)
	print("call function :check_qlc")
	print("param butType :" ,butType)
	print("param inStr :" ,inStr)
	local qxStr;
	local qjStr;
	local butNum = 0;
	local butPower = 1;
	local butStr = "";
	local itemList = {}
	local itemLen = 0;
	print("param 000")
	itemList = Split( inStr, "#" )
	print("param 123")
	itemLen = table.getn( itemList )
	print("param 333")
	qjStr = string.gsub( inStr, "#", "")

	print("param 0")
	--��ʽֱѡ 1#022#��ʽ����1**��ʽ����2��#11  022 = 2,0,0,1
	if  butType == '1' then
		if itemLen > 2 or itemLen < 1 or (itemList[2] and string.find(itemList[2],"%D")) then return 0 end
		if tonumber( itemList[2] ) then butPower = tonumber( itemList[2] ) else butPower = 1 end
		if butPower >99 or butPower < 1 then return 0 end
		xxStr = string.gsub(itemList[1], "*", "x")
		xxItem = Split(xxStr, "xx")
		print("param butType1")
		butNum = #xxItem
		qxStr = string.gsub( qjStr, "*", "0")
		if butNum > 5 or butNum < 1 or string.find(qxStr,"%D") then
			return 0
		end
		print("param butType2")
		for i=1,butNum do
			sortStr = sort_str( xxItem[i] )
			if sortStr ~= nil and string.len( sortStr) == 14 then
				butStr = butStr.."00"..format_num(butPower)..sortStr.."^"
			else
				return 0
			end
		end

	--��ʽ��ѡ��Ͷ 1#026#��ʽ����#���� 026 = 2,0,0,2
	elseif butType == '2' then
		if itemLen < 1 or itemLen > 2 or string.find(qjStr,"%D") or string.len(itemList[1]) ~= 14 or sort_str(itemList[1])==nil  then
			return 0
		end

		if tonumber( itemList[2] ) then butPower = tonumber( itemList[2] ) else butPower = 1 end
		if butPower >99 or butPower < 1 then return 0 end

		butNum = 1
		butStr = "00"..format_num( butPower )..sort_str(itemList[1]).."^"


	--��ʽ 1#023#��ʽ���� 023 = 2,0,0,3
	elseif butType == '3' then
		if itemLen < 1 or itemLen > 2 or string.find(qjStr,"%D") or string.len(itemList[1]) < 16 or string.len(itemList[1]) > 30 or sort_str(itemList[1])==nil  then
			return 0
		end

		if tonumber( itemList[2] ) then butPower = tonumber( itemList[2] ) else butPower = 1 end
		if butPower >99 or butPower < 1 then return 0 end

		butNum = combination( string.len(itemList[1])/2, 7)
		butStr = "10"..format_num( butPower )..sort_str(itemList[1]).."^"

	--������ѡ 1#027#������*�Ϻ��� 027 = 2,0,0,4
	elseif butType == '4' then
		if itemLen <1 or itemLen>2 then
			return 0
		end

		qxStr = string.gsub(itemList[1], "*", "")
		if  string.find(qxStr,"%D") or sort_str(qxStr)==nil or string.len(qxStr) < 16 then
			return 0
		end

		if tonumber( itemList[2] ) then butPower = tonumber( itemList[2] ) else butPower = 1 end
		if butPower >99 or butPower < 1 then return 0 end

		xItem = Split( itemList[1], "*")

		if table.getn( xItem ) ~= 2 or sort_str(xItem[1])==nil or sort_str(xItem[2])==nil or string.len(xItem[1]) >12 or string.len(xItem[1]) < 2 then
			return 0
		end

		danNum = string.len(xItem[1])/2
		tuoNum = string.len(xItem[2])/2

		butNum = combination(tuoNum, (7-danNum))
		butStr = "20"..format_num( butPower )..sort_str(xItem[1]).."*"..sort_str(xItem[2]).."^"



	else
		return 0
	end;
	return butNum,butPower,butStr,inStr
end
--================================�н���ѯ========================
function query_qlc(butType,queryStr,djStr)
	local butPower = 1;
	local itemList = {}
	local nTotalDT        -- //�ܵ������
	local nMaxRedDT        -- //��������л����Ÿ���
	local nMaxBlueDT         --//����������ر�Ÿ���
	local nTotal         --//���������
	local nMaxRed        -- //��������л����Ÿ���
	local nMaxBlue        -- //����������ر�Ÿ���
	local temp = {0, 0, 0, 0, 0, 0, 0}
	local nNum = {0, 0, 0, 0, 0, 0, 0}
	itemList = Split( queryStr, "#" )
	xxStr = string.gsub(itemList[1], "*", "x")
	xxItem = Split(xxStr, "xx")


	if tonumber( itemList[2] ) then butPower = tonumber( itemList[2] ) else butPower = 1 end
	bullStr = Split(djStr, "|")
	--��ʽ����
	if butType == '1' or butType == '2' then
		nTotal = 7
		for i = 1, table.getn(xxItem) do
			nMaxRed = ConputeBingoNum(xxItem[i],bullStr[1],2)
			nMaxBlue = ConputeBingoNum(xxItem[i],bullStr[2],2)
			temp = nNum
			nNum = QlcComppute(nTotal,nMaxRed,nMaxBlue)
			for j = 1,7 do
				nNum[j] = nNum[j] + temp[j]
			end
		end
	--��ʽ����
	elseif butType == '3' then
		nTotal = string.len(itemList[1]) / 2
		nMaxRed = ConputeBingoNum(itemList[1],bullStr[1],2)
		nMaxBlue = ConputeBingoNum(itemList[1],bullStr[2],2)
		nNum = QlcComppute(nTotal,nMaxRed,nMaxBlue)
	--���ϼ���
	elseif butType == '4' then
		xItem = Split(xxItem[1],"x")
		nTotal = string.len(xItem[1]) / 2 + string.len(xItem[2]) / 2
		nTotalDT = string.len(xItem[1]) / 2
		nMaxRedDT = ConputeBingoNum(xItem[1],bullStr[1],2)
		nMaxBlueDT = ConputeBingoNum(xItem[1],bullStr[2],2)
		nMaxRed = ConputeBingoNum(xItem[2],bullStr[1],2)
		nMaxBlue = ConputeBingoNum(xItem[2],bullStr[2],2)
		nNum = QlcCompputeDT(nTotal, nTotalDT, nMaxRedDT, nMaxBlueDT, nMaxRed, nMaxBlue)
	end
	for i = 1, 7 do
		nNum[i] = nNum[i] * butPower
	end
	return  nNum[1]..","..nNum[2]..","..nNum[3]..","..nNum[4]..","..nNum[5]..","..nNum[6]..","..nNum[7]

end

--test
--print(check_qlc('1',"01020304050607**30040501030806"))
--print(check_qlc('2',"33020304050607#12"))
--print(check_qlc('3',"3332313019020304050607#2"))
--print(check_qlc('4',"26272830*19020304050607#1"))

--for i=1,1000 do
--print(random_qlc('1',"3#2"))
--print(random_qlc('5',"010204#4#3"))
--print(random_qlc('5',"01020304#4"))
--end
--print(QlcComppute(19,7,0))
--print(QlcCompputeDT(10,4,3,0,3,1))
--print(query_qlc('1',"02030812132324#2","02040708132429|09"))
--print(query_qlc('2',"01020304050607080910111213141516171819#2","01020304050607|20"))
--print(query_qlc('3',"0102030405060708#3","01020304050607|08 "))
--print(query_qlc('4',"01020309*040506081415#2","01020304050607|08"))
